import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { PaymentOrder, PaymentStatus } from '@/database/entities/payment-order.entity';
import { CreatePaymentOrderDto, QueryPaymentOrdersDto, UpdatePaymentOrderDto } from './dto/payment.dto';
import { AlipayService } from './services/alipay.service';
import { WechatService } from './services/wechat.service';
import * as dayjs from 'dayjs';

@Injectable()
export class PaymentService {
  constructor(
    @InjectRepository(PaymentOrder)
    private paymentOrderRepository: Repository<PaymentOrder>,
    private alipayService: AlipayService,
    private wechatService: WechatService,
  ) {}

  async create(createPaymentOrderDto: CreatePaymentOrderDto, userId?: number) {
    const orderNo = this.generateOrderNo();
    
    const order = this.paymentOrderRepository.create({
      orderNo,
      userId,
      amount: createPaymentOrderDto.amount,
      paymentMethod: createPaymentOrderDto.paymentMethod,
      description: createPaymentOrderDto.description,
      clientIp: createPaymentOrderDto.clientIp,
      status: PaymentStatus.PENDING,
    });

    const savedOrder = await this.paymentOrderRepository.save(order);

    let paymentUrl: string;
    switch (createPaymentOrderDto.paymentMethod) {
      case 'alipay':
        paymentUrl = await this.alipayService.createPayment(savedOrder);
        break;
      case 'wechat':
        paymentUrl = await this.wechatService.createPayment(savedOrder);
        break;
      default:
        throw new BadRequestException('不支持的支付方式');
    }

    return {
      ...savedOrder,
      paymentUrl,
    };
  }

  async findAll(query: QueryPaymentOrdersDto) {
    const { page = 1, pageSize = 10, status, paymentMethod, startDate, endDate, keyword } = query;
    
    const queryBuilder = this.paymentOrderRepository.createQueryBuilder('order');

    if (status) {
      queryBuilder.andWhere('order.status = :status', { status });
    }

    if (paymentMethod) {
      queryBuilder.andWhere('order.paymentMethod = :paymentMethod', { paymentMethod });
    }

    if (startDate && endDate) {
      queryBuilder.andWhere('order.createTime BETWEEN :startDate AND :endDate', {
        startDate,
        endDate,
      });
    }

    if (keyword) {
      queryBuilder.andWhere(
        '(order.orderNo LIKE :keyword OR order.thirdPartyOrderNo LIKE :keyword OR order.description LIKE :keyword)',
        { keyword: `%${keyword}%` }
      );
    }

    const [list, total] = await queryBuilder
      .orderBy('order.createTime', 'DESC')
      .skip((page - 1) * pageSize)
      .take(pageSize)
      .getManyAndCount();

    return {
      list,
      total,
      page,
      pageSize,
    };
  }

  async findById(id: number): Promise<PaymentOrder> {
    const order = await this.paymentOrderRepository.findOne({ where: { id } });
    if (!order) {
      throw new NotFoundException('订单不存在');
    }
    return order;
  }

  async findByOrderNo(orderNo: string): Promise<PaymentOrder> {
    const order = await this.paymentOrderRepository.findOne({ where: { orderNo } });
    if (!order) {
      throw new NotFoundException('订单不存在');
    }
    return order;
  }

  async update(id: number, updatePaymentOrderDto: UpdatePaymentOrderDto): Promise<PaymentOrder> {
    const order = await this.findById(id);
    Object.assign(order, updatePaymentOrderDto);
    return this.paymentOrderRepository.save(order);
  }

  async handlePaymentCallback(paymentMethod: string, callbackData: any) {
    let orderNo: string;
    let isSuccess: boolean;
    let thirdPartyOrderNo: string;

    switch (paymentMethod) {
      case 'alipay':
        const alipayResult = await this.alipayService.verifyCallback(callbackData);
        orderNo = alipayResult.out_trade_no;
        isSuccess = alipayResult.trade_status === 'TRADE_SUCCESS';
        thirdPartyOrderNo = alipayResult.trade_no;
        break;
      case 'wechat':
        const wechatResult = await this.wechatService.verifyCallback(callbackData);
        orderNo = wechatResult.out_trade_no;
        isSuccess = wechatResult.result_code === 'SUCCESS';
        thirdPartyOrderNo = wechatResult.transaction_id;
        break;
      default:
        throw new BadRequestException('不支持的支付方式');
    }

    const order = await this.findByOrderNo(orderNo);
    
    if (order.status !== PaymentStatus.PENDING) {
      return order; // 避免重复处理
    }

    order.status = isSuccess ? PaymentStatus.SUCCESS : PaymentStatus.FAILED;
    order.thirdPartyOrderNo = thirdPartyOrderNo;
    order.callbackData = JSON.stringify(callbackData);
    order.completeTime = isSuccess ? new Date() : null;
    
    if (!isSuccess && callbackData.fail_reason) {
      order.failReason = callbackData.fail_reason;
    }

    return this.paymentOrderRepository.save(order);
  }

  async getPaymentStats(startDate?: string, endDate?: string) {
    const queryBuilder = this.paymentOrderRepository.createQueryBuilder('order');

    if (startDate && endDate) {
      queryBuilder.andWhere('order.createTime BETWEEN :startDate AND :endDate', {
        startDate,
        endDate,
      });
    }

    const [
      totalOrders,
      successOrders,
      totalAmount,
      todayOrders,
      methodStats,
    ] = await Promise.all([
      // 总订单数
      queryBuilder.getCount(),
      
      // 成功订单数
      queryBuilder.clone().andWhere('order.status = :status', { status: PaymentStatus.SUCCESS }).getCount(),
      
      // 总金额
      queryBuilder.clone()
        .select('SUM(order.amount)', 'total')
        .andWhere('order.status = :status', { status: PaymentStatus.SUCCESS })
        .getRawOne(),
      
      // 今日订单数
      queryBuilder.clone()
        .andWhere('DATE(order.createTime) = CURDATE()')
        .getCount(),
      
      // 支付方式统计
      queryBuilder.clone()
        .select(['order.paymentMethod', 'COUNT(*) as count', 'SUM(order.amount) as amount'])
        .andWhere('order.status = :status', { status: PaymentStatus.SUCCESS })
        .groupBy('order.paymentMethod')
        .getRawMany(),
    ]);

    const successRate = totalOrders > 0 ? (successOrders / totalOrders * 100).toFixed(2) : '0.00';

    return {
      totalOrders,
      successOrders,
      totalRevenue: parseFloat(totalAmount?.total || '0'),
      successRate: parseFloat(successRate),
      todayOrders,
      distribution: methodStats.map(stat => ({
        name: this.getPaymentMethodName(stat.paymentMethod),
        value: parseInt(stat.count),
        amount: parseFloat(stat.amount),
      })),
    };
  }

  private getPaymentMethodName(method: string): string {
    const methodMap = {
      alipay: '支付宝',
      wechat: '微信支付',
      bank: '银行卡',
      balance: '余额支付',
    };
    return methodMap[method] || method;
  }

  private generateOrderNo(): string {
    const timestamp = dayjs().format('YYYYMMDDHHmmss');
    const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
    return `PAY${timestamp}${random}`;
  }

  async cancelOrder(id: number): Promise<PaymentOrder> {
    const order = await this.findById(id);
    
    if (order.status !== PaymentStatus.PENDING) {
      throw new BadRequestException('只能取消待支付的订单');
    }

    order.status = PaymentStatus.CANCELLED;
    return this.paymentOrderRepository.save(order);
  }

  async refundOrder(id: number, reason?: string): Promise<PaymentOrder> {
    const order = await this.findById(id);
    
    if (order.status !== PaymentStatus.SUCCESS) {
      throw new BadRequestException('只能退款已支付成功的订单');
    }

    // 调用第三方退款接口
    let refundResult: any;
    switch (order.paymentMethod) {
      case 'alipay':
        refundResult = await this.alipayService.refund(order, reason);
        break;
      case 'wechat':
        refundResult = await this.wechatService.refund(order, reason);
        break;
      default:
        throw new BadRequestException('不支持的支付方式');
    }

    if (refundResult.success) {
      order.status = PaymentStatus.CANCELLED;
      order.failReason = `退款成功: ${reason || ''}`;
    }

    return this.paymentOrderRepository.save(order);
  }
}